老實說我決定要寫影像處理這個部分的時候還蠻猶豫的,因為在javascript 做影像處理的這個領域,IT邦之前其實就有蠻多寫的蠻不錯的文章。
例如第11屆鐵人賽 , lb01910483大大寫的 用 Javascript 當個影像魔術師。
不過既然都決定要寫了,那我也只能盡力去把這個章節寫完XD
話不多說,就讓我們開始吧。
大家不知道還有沒有印象我們在前些時候有講過canvas的像素操作(pixel manipulation)。
我們之前有講過canvas的imageData的提取方法,也有提到過最一個基本的像素處理案例實作:『拼字圖畫』。
相信之前有讀過我們的像素操作教學文的人應該已經對我們接下來要講的東西都有了一些基本的概念~
沒讀過或不熟的同學可以再回去讀一讀喔~之前的文連結在這邊: https://ithelp.ithome.com.tw/articles/10270233
我們在這一篇會先來簡單的熱個身! 從一些簡單的影像處理技術,還有簡單的色彩原理開始講解 ~
其實這個技巧我們在像素處理那篇有用過,但是當時並沒有很清楚地提出來講~
彩色轉灰階的原理其實很簡單,就是單純的把RGB channel 的值取平均
就像下面這樣:
function turnImageDataIntoGrayscale(imageData){
let data = imageData.data;
for(let i=0;i<data.length;i = i+4){
let r = data[i];
let g = data[i+1];
let b = data[i+2];
//取得rgb值得平均, 如此一來因為rgb都變成同一個數值
// 圖像就會變成灰階圖
let average = (r+g+b)/3
data[i] = data[i+1] = data[i+2] = average;
}
return imageData;
}
可能有些人會有點納悶,為什麼取平均就會變成
灰階圖呢? 其實可以稍微回憶一下每次在寫css要用灰階色時,灰階系列的顏色基本都是rgb為相同數值的組合(例如#333 就是rgb(51,51,51))~
反相顧名思義就是把色相(Hue)顛倒過來,而實作的方式很簡單,就是直接用255去扣掉當前的channel值就可以了
function invertImageData(imageData){
let data = imageData.data;
for(let i=0;i<data.length;i = i+4){
let r = data[i];
let g = data[i+1];
let b = data[i+2];
//直接用255去扣掉當前的channel值
data[i] = 255 - r;
data[i+1] = 255 - g;
data[i+2] = 255 - b;
}
return imageData;
}
在上面兩個案例中,也就是灰階化和反相,他們其實都是對色相(Hue)、彩度(Chroma)、明度(Value)的一種操作。
色相(Hue)、彩度(Chroma)、明度(Value) 在美術領域的色彩學中並稱『色彩三要素』,意思是說只要透過調節這三種要素的數值/占比,就可以產生任意顏色。
而在電腦編程的世界中,我們平常在寫樣式的時候通常是用到HEX色碼或者是RGB(A)制的顏色,但是其實還有另外兩種我們比較不常用到的格式,那就是HSV和HSL,這兩者的H和S代表的都是Hue(色相)和Saturate(飽和度),HSV的V是Value(明度),而HSL的L則是亮度(Ligntness)
Hue(色相) : 基本上跟色彩學 - 色彩三要素的色相(Hue)無異。Saturate(飽和度): 跟色彩學 - 色彩三要素的彩度(Chroma)有直接關係,但是不是等價,除此之外HSL和HSV的S計算方式略有不同。Value(明度): 跟色彩學 - 色彩三要素的明度(Value)有直接關係,但是不是等價。亮度(Ligntness): 雖然名稱不同,跟色彩學 - 色彩三要素的明度(Value)反而比較接近。
圖片來自 維基百科
從上圖我們可以看出HSL制和HSV制的差別主要就在於表示色彩亮度的Z軸部分(HSL會隨著L值的增加而變得更趨近於白色,但是HSV不會)
RGB與HSL/HSV 的相互轉換方法 可以讀這篇 : https://www.itread01.com/content/1549753775.html
到這邊我們就做完基本的熱身了 ~ 下一篇開始我們會實作一些比較有趣的案例,還是老樣子各位敬請期待 :D